package cs342.group1.messenger;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Collections;

import com.example.grouponemessenger.R;
import com.example.grouponemessenger.R.layout;
import com.example.grouponemessenger.R.menu;

import cs342.group1.messenger.MainActivity.GetAllMessagesForUser;
import cs342.group1.messenger.MainActivity.InitializeConversationList;
import cs342.group1.messenger.MainActivity.PutMessagesInDatabase;
import cs342.group1.messenger.MainActivity.TimeoutRequests;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class Conversation extends Activity {
	private int MyId;
	private int TheirId;
	private Database db; 
	ArrayList<Message> messagesWithUser = null;
	private AlertDialog.Builder dlgAlert;
	public static int staticID;
	
	private ListView conversation;
	private ConversationAdapter conversationAdapter;
	public static Context conversationContext;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		System.out.println("CREATED!!!!!!!!!!!!!!!!!!!!!!!");
		setContentView(R.layout.activity_conversation);
		conversationContext = this;
		dlgAlert  = new AlertDialog.Builder(this);
		db = new Database(this);
		conversation = (ListView) findViewById(R.id.conversation);
		//on click listener for messages
		conversation.setOnItemClickListener(new OnItemClickListener()
		{

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long arg3)
			{
				Message clickedContact = (Message) conversationAdapter.getItem(position);
				Toast.makeText(conversationContext, clickedContact.toString(), Toast.LENGTH_LONG).show();
				int messageId = clickedContact.CloudId;
				SaveMessageText task4 = new SaveMessageText();
				task4.execute(messageId);
				boolean success = false;
				try {
					success = task4.get();
				}
				catch (Exception e) {
					success = false;
				}
				
			}
			
		});
		Intent intent = getIntent();
		TheirId = intent.getIntExtra("userId", -1);
		
		db.open();
		MyId = db.CheckUserLoggedIn().CloudId;
		System.out.println("hiiiii setting myid and static id");
		//staticID = MyId;
		//pull user messages here
		Message[] messages;
		GetAllMessagesForUser task = new GetAllMessagesForUser();
		task.execute(MyId);
		try {
			messages = task.get();
		}
		catch (Exception e) {
			messages = new Message[0];
		}
		PutMessagesInDatabase task2 = new PutMessagesInDatabase();
		task2.execute(messages);
		try {
			//messages are now in android database, we can query and list names of conversations from here
			if(task2.get()){
				//Grab all messages with this user
				GetMessagesWithUser task3 = new GetMessagesWithUser();
				task3.execute(MyId, TheirId);
				try {
					messagesWithUser = task3.get();
					//Now do something with the messages
					updateConversation(messagesWithUser);
				}
				catch (Exception e) {
					messagesWithUser = new ArrayList<Message>();
				}
			}
		}
		catch (Exception e) {
			//error, display error or just log the user out
			System.out.print(e);
		}
	}
	
	public void SendMessage(View v){
		EditText messageText = (EditText)findViewById(R.id.NewMessageEditText);
		SendMessage task = new SendMessage();
		task.execute(Integer.toString(MyId), Integer.toString(TheirId), messageText.getText().toString());
		int messageId = -1;
		try {
			messageId = task.get();
			//Now do something with the messages
			
		}
		catch (Exception e) {
			messageId = -1;
		}
		if(messageId > 0){
			//put new message in array adapter here with id and message text
			Message message = new Message();
			message.CloudId = messageId;
			message.Message = messageText.getText().toString();
			message.FromUserId = MyId;
			message.ToUserId = TheirId;
			messagesWithUser.add(message);
			updateConversation(messagesWithUser);
		}
		messageText.setText("");
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_conversation, menu);
		return true;
	}
	
	
	/**
	 * Updates the messages on the page.
	 * @param messages An arraylist containing all the messages to be displayed.
	 */
	public void updateConversation(ArrayList<Message> messages)
	{
		Collections.sort(this.messagesWithUser);
		this.conversationAdapter = new ConversationAdapter(this,R.layout.my_messages_list_item,messages);
		this.conversation.setAdapter(conversationAdapter);
		this.conversation.post(new Runnable()
		{
			@Override
			public void run()
			{
				conversation.setSelection(conversationAdapter.getCount()-1);
			}
		});
	}
	
	
	public class GetAllMessagesForUser extends AsyncTask<Integer, Void, Message[]> {
		@Override
		protected Message[] doInBackground(Integer... params) {
			
			return new CloudHelper().GetAllMessagesForUser(params[0]);
		}
	}
	
	public class GetMessagesWithUser extends AsyncTask<Integer, Void, ArrayList<Message>> {
		@Override
		protected ArrayList<Message> doInBackground(Integer... params) {
			
			return db.GetMessagesWithUser(params[0], params[1]);
		}
	}
	public class PutMessagesInDatabase extends AsyncTask<Message[], Void, Boolean> {
		@Override
		protected Boolean doInBackground(Message[]... params) {
			db.open();
			db.DeleteAllMessages();
			for(Message m : params[0]){
				db.open();
				db.insertMessage(m);
			}
			return true;
		}
	}
	
	public class SendMessage extends AsyncTask<String, Void, Integer> {
		@Override
		protected Integer doInBackground(String... params) {
			db.open();
			Message message = new Message();
			message.CloudId = -1;
			message.FromUserId = Integer.parseInt(params[0]);
			message.FromUserName = "";
			message.ToUserId = Integer.parseInt(params[1]);
			message.ToUserName = "";
			message.Message = params[2];
			message.DateSend = new Date(0);
			message.ToKeep = false;
			message.FromKeep = false;
			
			db.insertMessage(message);
			return (new CloudHelper().SendMessage(Integer.parseInt(params[0]), Integer.parseInt(params[1]), params[2]));
		}
	}
	
	public class SaveMessage extends AsyncTask<String, Void, Integer> {
		@Override
		protected Integer doInBackground(String... params) {
			db.open();
			return (new CloudHelper().SendMessage(Integer.parseInt(params[0]), Integer.parseInt(params[1]), params[2]));
		}
	}
	
	public class SaveMessageText extends AsyncTask<Integer, Void, Boolean> {
		@Override
		protected Boolean doInBackground(Integer... params) {
			db.open();
			boolean fromKeep = false;
			int messageId = params[0];
			Message message = db.GetMessageByCloudMessageId(messageId);
			if(message.ToUserId == MyId){
				fromKeep = false;
			}
			else{
				fromKeep = true;
			}
			return new CloudHelper().SaveMessageText(messageId, fromKeep);
		}
	}
	
	public class TimeoutRequests extends AsyncTask<Void, Void, Void> {
		@Override
		protected Void doInBackground(Void... params) {
			int androidCount = -1;
			int cloudCount = -1;
			try {
				db.open();
				androidCount = db.GetMessageCount();
			}
			catch (Exception e) {
				
			}
			try {
				cloudCount = new CloudHelper().GetMessageCount(MyId);
				
			}
			catch (Exception e) {
				
			}
			
			if(cloudCount < 0|| androidCount < 0){
				
			}
			else if(cloudCount > androidCount){
				//display message for new messages
				int difference = cloudCount - androidCount;

				dlgAlert.setMessage("You have " + difference + " new message" + (difference > 1 ? "s" : ""));
				dlgAlert.setTitle("New Message");
				dlgAlert.setPositiveButton("Ok",
					    new DialogInterface.OnClickListener() {
					        public void onClick(DialogInterface dialog, int which) {
					          //dismiss the dialog  
					        	Message[] messages;
					    		GetAllMessagesForUser task = new GetAllMessagesForUser();
					    		task.execute(MyId);
					    		try {
					    			messages = task.get();
					    		}
					    		catch (Exception e) {
					    			messages = new Message[0];
					    		}
					    		PutMessagesInDatabase task2 = new PutMessagesInDatabase();
					    		task2.execute(messages);
					    		try {
					    			//messages are now in android database, we can query and list names of conversations from here
					    			if(task2.get()){
					    				//Grab all messages with this user
					    				GetMessagesWithUser task3 = new GetMessagesWithUser();
					    				task3.execute(MyId, TheirId);
					    				try {
					    					messagesWithUser = task3.get();
					    					//Now do something with the messages
					    					updateConversation(messagesWithUser);
					    				}
					    				catch (Exception e) {
					    					messagesWithUser = new ArrayList<Message>();
					    				}
					    			}
					    		}
					    		catch (Exception e) {
					    			//error, display error or just log the user out
					    			System.out.print(e);
					    		}
					    		
					        	new java.util.Timer().schedule( 
								        new java.util.TimerTask() {
								            @Override
								            public void run() {
								            	new TimeoutRequests().execute();
								            }
								        }, 
								        15000 
								);
					        }
					    });
				dlgAlert.setCancelable(true);
				Conversation.this.runOnUiThread(new Runnable() {

			        public void run() {
			        	try{
			        		dlgAlert.create().show();
			        	}
			        	catch(Exception e){
			        		//something happened with the dialog, oh well
			        	}

			        }
			    });
			}
			else{
				new java.util.Timer().schedule( 
				        new java.util.TimerTask() {
				            @Override
				            public void run() {
				            	new TimeoutRequests().execute();
				            }
				        }, 
				        15000 
				);
			}
			
			return null;
		}
	}
	@Override
	public void onPause() {
	    super.onPause();  // Always call the superclass method first
	    System.out.println("PAUSE!!!!!!!!!!!!!!!!!!!!!!!");
	}
	
	@Override
	public void onResume() {
	    super.onResume();  // Always call the superclass method first
	    new java.util.Timer().schedule( 
		        new java.util.TimerTask() {
		            @Override
		            public void run() {
		            	new TimeoutRequests().execute();
		            }
		        }, 
		        15000 
		);
	    
	}

}
